namespace GYLite
{    
    export class DB_STORE{
        public static readonly BATTLE:string = "battle";
    }
    export enum DB_OPER{
        GET,
        ADD,
        PUT,
        DELETE,
        CLEAR
    }
    export class IndexDBCtrl
    {
        constructor()
        {

        }
        
        /**打开数据库操作
         * @param  dbName 数据库名称
         * @param storeName 仓库名称（表名）
         * @param type 操作类型 参考DB_OPER常量
         * @param callBack 回调
         * @param data type为DB_OPER.ADD或DB_OPER.PUT的时候，提供的数据，{id:0}，数据必须带id作为唯一标识         
         * @param key 删除记录时提供
         * @param rangeKey 指定比较的字段名，默认id
        */
        public static openDBToOper(dbName:string, storeName:string, type:number, callBack:(code:number,data?:any)=>void=null, data:any[]=null, key:IDBKeyRange | IDBValidKey=null, rangeKey:string="id"):void
        {
            let s= this;            
            if(data == null && type == DB_OPER.ADD)return;
            if(key == null && type == DB_OPER.DELETE)return;
            let dbReq:IDBOpenDBRequest;            
            dbReq = indexedDB.open(dbName, Date.now());
            dbReq.onsuccess = (e)=>{                
                let db:IDBDatabase;
                db = e.target["result"];
                let transaction:IDBTransaction;
                let store:IDBObjectStore;
                transaction = db.transaction(storeName, "readwrite");
                store = transaction.objectStore(storeName);
                if(type == DB_OPER.GET)
                    s.getData(store,callBack, key)                
                else if(type == DB_OPER.ADD)
                    s.add(store,data,callBack, <IDBValidKey>key);
                else if(type == DB_OPER.PUT)
                    s.put(store,data,callBack, <IDBValidKey>key);
                else if(type == DB_OPER.CLEAR)
                    s.clearStore(store,callBack);
                else if(type == DB_OPER.DELETE)
                    s.delete(store,key,callBack,rangeKey);
                
                transaction.oncomplete = (e)=>{
                    let db:IDBDatabase;
                    db = (<any>e.target).db;
                    db.close();                        
                };
                transaction.onerror = (e)=>{
                    let db:IDBDatabase;
                    db = (<any>e.target).db;
                    db.close();                        
                };
                transaction.onabort = (e)=>{
                    let db:IDBDatabase;
                    db = (<any>e.target).db;
                    db.close();                        
                };
            };
            dbReq.onerror = (e)=>{
                SysError.DB_ERROR.throwError([dbName + " openDB error"]);                
            };
            dbReq.onupgradeneeded = (e)=>{
                let db:IDBDatabase;
                db = e.target["result"];                
                if(!db.objectStoreNames.contains(storeName))
                    db.createObjectStore(storeName,{keyPath:"id"});
            };
        }
        /**添加记录（同名数据会报错）**/
        protected static add(store:IDBObjectStore,data:any[],func:(errcode:number,data?:any[])=>void=null, key: IDBValidKey=null):void
        {            
            let i:number,len:number,count:number;            
            let idbReq:IDBRequest;     
            count = len = data.length;
            for(i=0;i<len;++i)
            {                  
                idbReq = key?store.add(data[i], key):store.add(data[i]);
                idbReq.onsuccess = (ev:Event)=>{
                    --count;
                    if(count == 0)
                    {
                        if(func!=null)
                            func(0);
                    }
                };
                idbReq.onerror = (ev:Event)=>{
                    --count;
                    if(count == 0)
                    {
                        if(func!=null)
                            func(1);
                    }
                };
            }
        }
        /**添加记录（同名数据会覆盖）**/
        protected static put(store:IDBObjectStore,data:any[],func:(errcode:number,data?:any[])=>void=null, key:IDBValidKey=null):void
        {            
            let i:number,len:number,count:number;            
            let idbReq:IDBRequest;     
            count = len = data.length;
            for(i=0;i<len;++i)
            {                  
                idbReq = key?store.put(data[i], key):store.put(data[i]);
                idbReq.onsuccess = (ev:Event)=>{
                    --count;
                    if(count == 0)
                    {
                        if(func!=null)
                            func(0);
                    }
                };
                idbReq.onerror = (ev:Event)=>{
                    --count;
                    if(count == 0)
                    {
                        if(func!=null)
                            func(1);
                    }
                };
            }
        }
        /**删除记录
         * @param store 仓库
         * @param key 删除的行字段名，可以用IDBKeyRange指定范围，指定范围时,key默认为id
        */
        protected static delete(store:IDBObjectStore, key:IDBValidKey | IDBKeyRange,func:(errcode:number,data?:any[])=>void=null, rangeKey:string="id"):void
        {
            let idbReq:IDBRequest;
            if(key instanceof IDBKeyRange)
            {   
                idbReq = store.openCursor();
                idbReq.onsuccess = function(event) {                    
                    let cursor = (<IDBRequest>event.target).result;
                    if (cursor) {
                        let time = cursor.value[rangeKey];
                        // 将日期字符串转换为Date对象进行比较（这里假设date字段已经是Date对象，如果不是，则需要转换）
                        // 注意：由于我们之前将日期存储为字符串，这里需要先将字符串转换回Date对象进行比较
                        if ((key.upper == null || time < key.upper) && (key.lower == null || time > key.lower))
                        {
                            idbReq = store.delete(cursor.key);
                        }
                        cursor.continue();
                    }                     
                };                
            }
            else 
            {
                idbReq = store.delete(key);
                idbReq.onsuccess = (ev:Event)=>{
                    if(func!=null)
                        func(0);
                };
            }          
                
            idbReq.onerror = (ev:Event)=>{
                if(func!=null)
                    func(1);
            };               
        }
        /**获取仓库数据*/
        protected static getData(store:IDBObjectStore,func:(errcode:number,data?:any[])=>void, queryKey: IDBKeyRange | IDBValidKey=null, count:number=NaN):void
        {
            let req:IDBRequest;
            if(queryKey == null)
                req = store.getAll();
            else
                req = count==count?store.getAll(queryKey,count):store.get(queryKey);
            req.onerror = (e)=>{
                if(func!=null)
                    func(1);
            };
            req.onsuccess = (e)=>{                
                if(func!=null)
                    func(0,req.result);
            };
        }
        /**清理仓库*/
        protected static clearStore(store:IDBObjectStore,func:(errorCode:number)=>void):void
        {            
            let req:IDBRequest = store.clear();
            req.onerror = (e)=>{
                if(func!=null)
                    func(1);
            };
            req.onsuccess = (e)=>{                
                if(func!=null)
                    func(0);
            };
        }
    }
}